package itheima04;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/*
    反射调用get_set方法
    步骤:
        1.获取Class类型的对象(三种方式,建议使用第三种forName)
        2.Class类型的对象 获取 成员方法对象
        3.执行成员方法对象
            java.lang.reflect.Method类   成员方法
            public Object invoke(Object obj,Object... args): 对带有指定参数的指定对象调用由此 Method 对象表示的底层方法。
                参数:
                    1.Object obj: 成员方法的执行,必须有对象的支持
                    2.Object... args: 执行方法时,该方法需要的具体的参数
                返回值: java.lang.Object类型
                    方法执行的结果,被封装成一个Object返回
                    1.没有返回值的方法: 返回一个null
                    2.有返回值的方法: Object对象中,封装了具体的结果



        对比: 调用setName方法
        假设: Person对象p,setName方法对象m

        没有使用反射之前: p.setName("张三")
        使用反射: m.invoke(p,"张三")



 */
/*public class Demo05Invoke {
    public static void main(String[] args) throws Exception {
        //1.获取Class类型的对象(三种方式,建议使用第三种forName)
        Class<?> c = Class.forName("domain.Person");

        //成员方法的调用,需要对象的支持
        //快捷方式,创建一个对象
        //调用有参构造
        Object obj = c.newInstance();
        //Person{name='null', age=0}
        System.out.println(obj);
        //2.获取setName方法对象
        Method setNameMethod = c.getMethod("setName", String.class);
        //3.执行setName方法对象
        Object result = setNameMethod.invoke(obj, "柳岩");
        //setName没有返回值的方法，返回个null
        System.out.println(result);//null
        //Person{name='柳岩', age=0}
        System.out.println(obj);

        //2.获取getName方法对象
        //public String getName() {return name;}
        Method getNameMethod = c.getMethod("getName");

        //3.执行getName方法对象
        //obj为Person{name='柳岩', age=0}
        result = getNameMethod.invoke(obj);
        //返回值为name，name为柳岩
        System.out.println(result);

    }
}*/

public class Demo05Invoke {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class<?>c=Class.forName("domain.Person");
        //成员方法的调用,需要对象的支持
        //快捷方式,创建一个对象
        //获取类的对象
        Object o=c.newInstance();
        //Person{name='null', age=0}
        System.out.println(o);
        //获取setName方法
        Method setName = c.getMethod("setName", String.class);
        System.out.println(setName);
        Object wkr = setName.invoke(o, "wkr");
        //setName没有返回值的方法，返回个null
        System.out.println(wkr);
        //Person{name='wkr', age=0}
        //无参构造函数有值，但不返回对应值
        System.out.println(o);

         Method getAge = c.getMethod("getAge");
         Object invoke = getAge.invoke(o);
         //0
         System.out.println(invoke);
         //方法里面有啥参数类型就放啥没有就不放
         Method getName = c.getMethod("getName");
         Object invoke1 = getName.invoke(o);
         //wkr
         System.out.println(invoke1);

         //没放方法
         Method setAge = c.getMethod("setAge", int.class);
         //调用有参数的方法必须对相对应参数设值
        Object invoke2 = setAge.invoke(o,18);
        //没有返回值返回null
        System.out.println(invoke2);
        //Person{name='wkr', age=18}
        System.out.println(o);



    }
}